#ifndef IINSTANCE3D_H_INCLUDED
#define IINSTANCE3D_H_INCLUDED

#include "IInstance.h"

/// Information
class IInstance3D : public IInstance {
protected:
private:
	sTransformationData3D m_InstanceData;

public:
	/// Get transformational parameters
	vec3r GetViewVector	( ePIE_PARAMSTATE state = NOW ) const { return m_InstanceData.m_Transformation.GetViewVector( ); }
	vec3r GetUpVector		( ePIE_PARAMSTATE state = NOW ) const { return m_InstanceData.m_Transformation.GetUpVector( ); }
	vec3r GetRightVector	( ePIE_PARAMSTATE state = NOW ) const { return m_InstanceData.m_Transformation.GetRightVector( ); }
	vec3r GetScale			( ePIE_PARAMSTATE state = NOW ) const { return m_InstanceData.m_Scale; }
	vec3r GetShear			( ePIE_PARAMSTATE state = NOW ) const { return m_InstanceData.m_Shear; }
	quatr GetOrientation	( ePIE_PARAMSTATE state = NOW ) const { return m_InstanceData.m_Orientation; }
	vec3r GetPosition		( ePIE_PARAMSTATE state = NOW ) const { return m_InstanceData.m_Transformation.GetTranslate( ); }
	vec3r GetVelocity		( ePIE_PARAMSTATE state = NOW ) const { return m_InstanceData.m_Velocity; }
	quatr GetSpinVelocity( ePIE_PARAMSTATE state = NOW ) const { return m_InstanceData.m_SpinVelocity; }
	real  GetAccel			( ePIE_PARAMSTATE state = NOW ) const { return m_InstanceData.m_Acceleration; }
	real  GetSpinAccel	( ePIE_PARAMSTATE state = NOW ) const { return m_InstanceData.m_SpinAcceleration; }
	mat4r GetTransform	( ePIE_PARAMSTATE state = NOW ) const { return m_InstanceData.m_Transformation; }
	real  GetClock			( ePIE_PARAMSTATE state = NOW ) const { return m_InstanceData.m_Clock; }
	virtual void  GetTransformData( sTransformationData3D **data )  const { if(data) *data = NULL; }
	virtual void  GetTransformData( sTransformationData2D **data )  const { if(data) *data = NULL; }

	/// Set transformational parameters
	void SetViewVector	( cvec3r &view,	ePIE_PARAMSTATE state = NOW );
	void SetUpVector		( cvec3r &up,		ePIE_PARAMSTATE state = NOW );
	void SetRightVector	( cvec3r &right,	ePIE_PARAMSTATE state = NOW );
	void SetScale			( cvec3r &scale,	ePIE_PARAMSTATE state = NOW );
	void SetShear			( cvec3r &shear,	ePIE_PARAMSTATE state = NOW );
	void SetOrientation	( cquatr &orient,	ePIE_PARAMSTATE state = NOW );
	void SetPosition		( cvec3r &pos,		ePIE_PARAMSTATE state = NOW );
	void SetVelocity		( cvec4r &vel,		ePIE_PARAMSTATE state = NOW );
	void SetSpinVelocity	( cquatr &svel,	ePIE_PARAMSTATE state = NOW );
	void SetAccel			( creal  &accel,	ePIE_PARAMSTATE state = NOW );
	void SetSpinAccel		( creal  &saccel,	ePIE_PARAMSTATE state = NOW );
	void SetTransform		( cmat4r &trans,	ePIE_PARAMSTATE state = NOW );
	void SetClock			( creal  &clock,	ePIE_PARAMSTATE state = NOW );

	/// Movement planning
	void MoveToward		( uint obj, creal &spd, bool automatic = false ) { }
	void MoveTo				( cvec3r &pos, creal &spd ) { }
	void MoveToward		( cvec3r &dir, creal &spd ) { }
	void Move				( ) { }

	/// Movement immediate
	void StepToward		( uint obj, creal &spd, creal &dtime );
	void StepTo				( cvec3r &pos, creal &spd, creal &dtime );
	void StepToward		( cvec3r &dir, creal &spd, creal &dtime );
	void StepForward		( creal &spd, creal &dtime );
	void StepRight			( creal &spd, creal &dtime );
	void StepUp				( creal &spd, creal &dtime );

	/// Orientation
	void YawPitchRoll		( creal &yaw, creal &pitch, creal &roll );
	void YawPitch			( creal &yaw, creal &pitch );
	void LookAt				( uint obj, bool automatic = false );
	void LookAt				( cvec3r &pos );
	void Yaw					( creal &deg );
	void Pitch				( creal &deg );
	void Roll				( creal &deg );
	void Look				( );

			    // Constructor & Destructor
			    IInstance3D() : IInstance( ), m_InstanceData( ) { }
				~IInstance3D() { }
};

#endif // IINSTANCE3D_H_INCLUDED
